<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018-09-29
 * Time: 13:48
 */

namespace backend\controllers;
use app\models\AuthItemChild;
use mdm\admin\components\Configs;
use mdm\admin\components\Helper;
use mdm\admin\models\AuthItem;
use mdm\admin\models\Route;
use mdm\admin\models\searchs\AuthItem as AuthItemSearch;
use yii\helpers\ArrayHelper;
use yii\rbac\Item;

class QxPermissionController extends \mdm\admin\controllers\PermissionController
{

    /**
     * {@inheritdoc}
     * @see \yii\web\Controller::beforeAction()
     */
    public function beforeAction($action)
    {
        date_default_timezone_set('PRC');//设置时间时区为中国
        header("Content-type:application/x-www-form-urlencoded text/html; charset=utf-8");//设置格式为utf-8
        header('Access-Control-Allow-Origin:'.\Yii::$app->components['allowOutHttp']);
        header("Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE");
        header('Access-Control-Allow-Headers:X-Requested-With, origin, content-type, accept');
        header('Access-Control-Allow-Credentials: true');
        return true;
    }

    /**
     * 将数据打包成 layui可以识别的数据格式
     * @param $count
     * @param $all
     * @return array
     */
    public function packData($count,$all){
        $res = [];
        $res['code'] = 0;
        $res['msg'] = "";
        $res['count'] = $count;
        $res['data'] = $all;
        return json_encode((object)$res);
    }

    public function actionList()
    {
        $searchModel = new AuthItemSearch(['type' => $this->type]);
        $dataProvider = $searchModel->search(\Yii::$app->request->getQueryParams());
        $all = array_values(ArrayHelper::toArray($dataProvider->allModels,'post'));
        $count = $dataProvider->count;
        //必须要把数组转化为对象，前端固定的格式
        return $this->packData($count,$all);
    }

    /**
     * Creates a new AuthItem model.
     * If creation is successful, the browser will be redirected to the 'view' page.
     * @return mixed
     */
    public function actionCreate()
    {
        $model = new AuthItem(null);
        $model->type = $this->type;
        if ($model->load(\Yii::$app->getRequest()->post()) && $model->save()) {
            $res['data'] = ArrayHelper::toArray($model->getItem());
            $res['res'] = 1;
        } else {
            $error = array_values($model->getErrors());
            $res['data'] = isset($error[0][0])?$error[0][0]:"";
            $res['res'] = 0;
        }
        return json_encode($res);
    }

    /**
     * Updates an existing AuthItem model.
     * If update is successful, the browser will be redirected to the 'view' page.
     * @param  string $id
     * @return mixed
     */
    public function actionUpdate($id)
    {
        $model = $this->findModel($id);
        $res = "";
        if ($model->load(\Yii::$app->getRequest()->post()) && $model->save()) {
            $res['data'] = ArrayHelper::toArray($model->getItem());
            $res['res'] = 1;
        }else{
            $error = array_values($model->getErrors());
            $res['data'] = isset($error[0][0])?$error[0][0]:"";
            $res['res'] = 0;
        }
        return json_encode($res);
    }
    public function addChildren($model,$items)
    {
        $manager = Configs::authManager();
        $success = 0;
        if ($model->getItem()) {
            foreach ($items as $name) {
                $child = $manager->getPermission($name);
                if ($model->type == 2 && $child === null) {
                    $child = (new \app\models\AuthItem())->find()->where(['name'=>$name])->one();
                }
                try {
                    $manager->addChild($model->getItem(), $child);
                    $success++;
                } catch (\Exception $exc) {
                    \Yii::error($exc->getMessage(), __METHOD__);
                }
            }
        }
        if ($success > 0) {
            Helper::invalidate();
        }
        return $success;
    }

    /**
     * Remove an item as a child of another item.
     * @param array $items
     * @return int
     */
    public function removeChildren($model,$items)
    {
        $manager = Configs::authManager();
        $success = 0;
        if ($model->getItem() !== null) {
            foreach ($items as $name) {
                $child = $manager->getPermission($name);
                if ($this->type == 2 && $child === null) {
                    $child = (new \app\models\AuthItem())->find()->where(['name'=>$name])->one();
                }
                try {
                    $manager->removeChild($model->getItem(), $child);
                    $success++;
                } catch (\Exception $exc) {
                    Yii::error($exc->getMessage(), __METHOD__);
                }
            }
        }
        if ($success > 0) {
            Helper::invalidate();
        }
        return $success;
    }
    /**
     * Deletes an existing AuthItem model.
     * If deletion is successful, the browser will be redirected to the 'index' page.
     * @param  string $id
     * @return mixed
     */
    public function actionDelete($id)
    {
        $model = $this->findModel($id);
        Configs::authManager()->remove($model->item);
        Helper::invalidate();
        $res['data'] = "";
        $res['res'] = 1;
        return json_encode($res);
    }

    public function actionView($id)
    {
        $model = $this->findModel($id);
        $opts = $this->getItems_($model);
        $res['data'] = $opts;
        $res['res'] = 1;
        return json_encode($res);
    }

    /**
     * Get items
     * @return array
     */
    public function getItems_($model)
    {
        $item = new \app\models\AuthItem();
        $all = $item->find()->where(['type'=>3])->all();
        $available = [];
        foreach ($all as $item) {
            $available[$item->name] = $item->name;
        }
        $assigned = [];
        $itemChild = new AuthItemChild();
        $items = $itemChild->find()->where(['parent'=>$model->name])
            ->select('i.*,auth_item_child.*')
            ->leftJoin('auth_item as i','i.name=auth_item_child.parent')
            ->asArray()
            ->all();
        foreach ($items as $item) {
            $assigned[$item['child']] = $item['child'];
            unset($available[$item['child']]);
        }
        unset($available[$model->name]);
        return [
            'available' => $available,
            'assigned' => $assigned,
        ];
    }

    /**
     * 前端的 拿到登陆用的token
     * @return boolean
     */
    public function actionFrontCsrfToken()
    {
        $request = \Yii::$app->getRequest();
        if ($request->enableCsrfCookie || $this->enableSession) {
            return $_POST[\Yii::$app->components['request']['csrfParam']] = $request->getCsrfToken(true);
        }
    }
    public function actionAssign($id)
    {
        $items = \Yii::$app->getRequest()->post('items', []);
        $res = [];
        if (empty($items[0])){//没有选择角色
            $res['data'] = "请选择角色";
            $res['res'] = 0;
            return json_encode($res);
        }
        $model = $this->findModel($id);
        $success = $this->addChildren($model,$items);
        $optsDeal = $this->getItems_($model);
        $res['data'] = $optsDeal;
        $res['items'] = $items;
        $res['res'] = $success>0?1:0;
        return json_encode($res);

    }
    public function actionRemove($id)
    {
        $items = \Yii::$app->getRequest()->post('items', []);
        $res = [];
        if (empty($items[0])){//没有选择角色
            $res['data'] = "请选择角色";
            $res['res'] = 0;
            return json_encode($res);
        }
        $model = $this->findModel($id);
        $success = $this->removeChildren($model,$items);
        $optsDeal = $this->getItems_($model);
        $res['data'] = $optsDeal;
        $res['items'] = $items;
        $res['res'] = $success>0?1:0;
        return json_encode($res);
    }

    /**
     * Finds the AuthItem model based on its primary key value.
     * If the model is not found, a 404 HTTP exception will be thrown.
     * @param string $id
     * @return AuthItem the loaded model
     * @throws NotFoundHttpException if the model cannot be found
     */
    protected function findModel($id)
    {
        $auth = Configs::authManager();
        $item = $this->type === Item::TYPE_ROLE ? $auth->getRole($id) : $auth->getPermission($id);
        if ($item) {
            return new AuthItem($item);
        } else {
            throw new NotFoundHttpException('The requested page does not exist.');
        }
    }
}